package com.express.core.controller;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.express.aop.AuthToken;
import com.express.common.SysParamterUtil;
import com.express.conf.WechatConfig;
import com.express.constants.Constants;
import com.express.dto.OrdersDto;
import com.express.dto.OrdersQueryDto;
import com.express.entity.Address;
import com.express.entity.UserOrders;
import com.express.mybatis.Result;
import com.express.service.IAddressService;
import com.express.service.IOrderService;
import com.express.util.DateUtils;
import com.express.util.IOUtil;
import com.express.util.RandomNumber;
import com.express.util.wx.WeixinUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.Errors;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;

import static java.util.Comparator.comparing;
import static java.util.stream.Collectors.collectingAndThen;
import static java.util.stream.Collectors.toCollection;

/**
 * 寄快递控制类
 */
@Controller
//@Api(tags = "订单管理", value = "订单管理相关接口")
public class SendExpController {

    private static final Logger logger = LoggerFactory.getLogger(SendExpController.class);

    @Autowired
    IOrderService orderService;

    @Autowired
    IAddressService addressService;

    @Autowired
    SysParamterUtil paramterUtil;

//    @Autowired
//    private WebSocketServer webSocket;

    /**
     * 跳转寄快递页面
     *
     * @return
     */
    @RequestMapping("sendIndex")
    public ModelAndView toSendIndex(HttpServletRequest request) {
        String orderId = request.getParameter("id") == null ? "" : request.getParameter("id");
        ModelAndView modelAndView = new ModelAndView();
        UserOrders order = new UserOrders();
        if (StringUtils.isNotBlank(orderId)) {
            order = orderService.getOrder(Integer.valueOf(orderId));
        }
        // 生成系统单号
//       if(StringUtils.isBlank(order.getOrderNo())){
//           order.setOrderNo(RandomNumber.getOrderNo("G"));
//       }
        modelAndView.addObject("order", order);
        modelAndView.setViewName("send");
        // 设置测试用户
//        request.getSession().setAttribute("userId",16);
        return modelAndView;
    }


    @RequestMapping("toSystemWeb")
    public void toSystemWeb(HttpServletRequest request, HttpServletResponse resp) throws Exception {
        String redirectUri = "http://localhost:8889/";
        resp.sendRedirect(redirectUri);
    }

    /**
     * 保存订单
     *
     * @return
     */
//    @AuthToken(source = 1)
    @RequestMapping(value = "saveOrder", method = RequestMethod.POST)
    @ResponseBody
    public Result saveOrder(HttpServletRequest request, OrdersDto orderDto, Errors bindingResult) {
        Result result = null;
        UserOrders orders = null;
        try {
            // 验证是否通过
            if (bindingResult.hasErrors()) {
                result = new Result(bindingResult.getAllErrors().get(0).getDefaultMessage(), 201, false);
                return result;
            }
            logger.info("请求订单参数：{}", JSONUtil.toJsonStr(orderDto));
            String userId = request.getSession().getAttribute("userId") == null ? "" : request.getSession().getAttribute("userId").toString();
//            String userId = "16";
            if (StringUtils.isBlank(userId)) {
                userId = orderDto.getUserId().toString();
                logger.info("不登录录单 ：{}", userId);
            }
            JSONObject billNumber = new JSONObject();
            if (orderDto != null) {
                orders = new UserOrders();
//                logger.info("创建订单时保存的发送人的名字和电话：{},{},地址是：{}", orderDto.getSendName(), orderDto.getSendPhone()
//                        , orderDto.getSendCompany());
                BeanUtils.copyProperties(orderDto, orders);
                // 判断是否更新
                if (orderDto.getId() != null) {
                    if (StringUtils.isNotBlank(orderDto.getReceiveDate())) {
                        orders.setReceiveDate(new Date(DateUtils.strToLong13(orderDto.getReceiveDate())));
                    }
                    orders.setUpdateDate(new Date());
                    checkAddress(orderDto, orders, request);
                    orderService.update(orders);
                    noticeAdmin(orders, "更新订单");
                } else {
                    logger.info("保存订单。。。");
                    orders.setUserId(Integer.valueOf(userId));
                    //orders.setOrderNo(RandomNumber.getOrderNo("G"));
                    if (StringUtils.isNotBlank(orderDto.getReceiveDate())) {
                        orders.setReceiveDate(DateUtil.parse(orderDto.getReceiveDate().replaceAll("[^\\x20-\\x7E]", " "), DatePattern.NORM_DATETIME_PATTERN));
                    }
                    // 生成预约单
                    orders.setAppointmentNo(RandomNumber.getOrderNo(Constants.ENV_PREFIX, ""));
                    // 托运单号
                    String oddNumber = paramterUtil.getParametValue(Constants.ENV_ORDER,true).toString();
//                    orders.setOddNumber(RandomNumber.getOrderNo(Constants.ENV_PREFIX,"",""));
                    orders.setOddNumber(oddNumber);
                    billNumber.put("billNumber", orders.getOddNumber());
                    paramterUtil.setParametValue(Constants.ENV_ORDER, orders.getOddNumber());
                    // 增加前缀
                    orders.setOrderNo(Constants.ENV_PREFIX + orders.getOrderNo());
                    orders.setCreateDate(new Date(System.currentTimeMillis()));
                    orders.setCreator("system");
                    orders.setUpdateDate(new Date(System.currentTimeMillis()));
                    orders.setUpdator("system");
                    orders.setStatus(1);
                    orders.setIsRead(0);
                    checkAddress(orderDto, orders, request);
                    orderService.save(orders);
                    // 通知后台有新单了
                    orderService.loadNewOrder(orders.getSendPhone());
//                  webSocket.sendAllMessage(orders.getSendPhone());
                    noticeAdmin(orders, "下单");
                }
                result = new Result("保存成功", 200, true);
                result.setData(billNumber);
                logger.info("订单保存成功：{}", JSONUtil.toJsonStr(result));
            } else {
                result = new Result("请检需要保存的选项是否为空！", 201, false);
            }
        } catch (Exception e) {
            e.printStackTrace();
            result = new Result("保存失败", 204, false);
        }
        try {
            // 同步订单到快递100
//            orderService.doOrder(orders);
        } catch (Exception e) {
            logger.error("同步订单失败", e);
        }
        return result;
    }

    /**
     * 检查地址信息
     *
     * @param orderDto
     * @param orders
     * @param request
     */
    private void checkAddress(OrdersDto orderDto, UserOrders orders, HttpServletRequest request) {
        // 检查一下保存地址是否正确

        // 保存发件人地址
        if (!StringUtils.isEmpty(orderDto.getSendIsUse()) && orderDto.getSendIsUse().equals("1")) {
            saveAddress(orders, 0, orderDto.getSendPhone(), orderDto.getSendCompany(), request);
        }
    }


    /**
     * 保存常用地址
     *
     * @param address
     */
    private void saveAddress(UserOrders order, int type, String phone, String address, HttpServletRequest request) {
        if (StringUtils.isNotBlank(address)) {
            logger.info("保存地址。。。开始");
            // 查询是否存在
            Address address1 = queryAddress(type, phone, address, request);
            if (address1 == null) {
                Address userAddress = new Address();
                userAddress.setUserId(order.getUserId());
                userAddress.setType(type);
                userAddress.setPhone(order.getSendPhone());
                userAddress.setName(order.getSendName());
                userAddress.setIsUse(1);
                // 手机 姓名 保存到地址栏中
//                userAddress.setAddress(order.getSendName()+","+order.getSendPhone()+","+address);
                userAddress.setAddress(address);
                userAddress.setCreateDate(new Date());
                userAddress.setStatus(1);
                addressService.save(userAddress);
                logger.info("保存地址成功");
            }
        }
    }

    /**
     * 查询地址信息
     *
     * @param address
     */
    private Address queryAddress(int type, String phone, String address, HttpServletRequest request) {
        // 查询是否存在
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("type", type);
        paramMap.put("address", address);
        paramMap.put("phone", phone);
        paramMap.put("userId", request.getSession().getAttribute("userId"));
        List<Address> list = addressService.query(paramMap);
        logger.info("list size is ", list.size());
        if (list == null || list.size() == 0) {
            logger.info("不存在");
        } else {
            return list.get(0);
        }
        return null;
    }

    /**
     * 通知管理人员
     */
    private void noticeAdmin(UserOrders orders, String title) {
        // 通知客服人员
        Object ids = paramterUtil.getParametValue("sendmsg");
        if (null != ids) {
            String[] opids = ids.toString().split(",");
            // 封装参数
            Map<String, String> map = new HashMap<>();
            map.put("first", "您好，" + orders.getSendName() + "客户手机号" + orders.getSendPhone() + "已" + title + "成功，请关注。");
            map.put("keyword1", orders.getOrderNo());
            Map<String, Object> param = new HashMap<>();
            param.put("id", orders.getReceiveId());
            String name = Optional.ofNullable(addressService.query(param))
                    .map(u -> u.get(0).getName()).orElse("");
            map.put("keyword2", orders.getSendName());
            map.put("keyword3", orders.getSendPhone());
            map.put("keyword4", name);
            map.put("keyword5", DateUtils.format(new Date(), "yyyy年MM月dd日 HH:mm"));
            map.put("remark", "请您跟进处理！");
            for (String str : opids) {
                WeixinUtil.sendDataToTemp(str, WechatConfig.WEIXIN_KF_MSGID, map);
            }
        }
    }

    /**
     * 获取地址列表
     *
     * @return
     */
    @GetMapping("getAddressList")
    @ResponseBody
    public Result getAddressList(String type, HttpServletRequest request) {
        Result result = null;
        try {
            Map<String, Object> paramMap = new HashMap<>();
            paramMap.put("type", type);
            // 加载用户保存的常用地址
            if (StringUtils.isNotBlank(type) && type.equals("0")) {
                String userId = request.getSession().getAttribute("userId") == null ? "" : request.getSession().getAttribute("userId").toString();
                if (StringUtils.isNotBlank(userId)) {
                    paramMap.put("status", 1);
                    paramMap.put("userId", userId);
                    //paramMap.put("isgroup","address");
                }
            }
            List<Address> list = addressService.query(paramMap);
            List<Address> newList = null;
            if (null != list && list.size() > 0) {
                // 根据地址去重复 把最新创建的排在前面
                newList = list.stream().collect(
                        collectingAndThen(
                                toCollection(() -> new TreeSet<>(comparing(Address::getAddress))), ArrayList::new)

                );
                result = new Result();
                result.setData(newList);
            } else {
                result = new Result();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 删除地址
     *
     * @return
     */
    @GetMapping("delAddress")
    @ResponseBody
    public Result delAddress(String id) {
        Result result = null;
        if (StringUtils.isNotBlank(id)) {
            addressService.invalid(Integer.valueOf(id));
            result = new Result();
        }
        return result;
    }

    @PostMapping({"/upFile"})
    @ResponseBody
    public String upFile(MultipartFile file) {
        try {
            String fileisName = "";
            if (!file.isEmpty()) {
                String fileName = file.getOriginalFilename();
//                String prefix = fileName.substring(fileName.lastIndexOf("."));
                fileisName = IOUtil.saveFile(file, fileName, IOUtil.BASE_PATH, 5);
            }
            JSONObject object = new JSONObject();
            object.put("code", 200);
            object.put("data", fileisName);
            return object.toJSONString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "上传失败";
    }

    @PostMapping({"/delFile"})
    @ResponseBody
    public String delFile(MultipartFile file, String filePath) {
        if (!file.isEmpty()) {
//            String fileName = file.getOriginalFilename();
            // 删除旧的
            IOUtil.delFile(IOUtil.getFileParentPath(), filePath);
        }
        JSONObject object = new JSONObject();
        object.put("code", 200);
        object.put("data", "删除完成");
        return object.toJSONString();
    }

    /**
     * 面单
     *
     * @return
     */
    @RequestMapping(value = "labelOrder", method = RequestMethod.POST)
    @ResponseBody
//    @ApiOperation(value = "面单")
    public Result labelOrder(OrdersDto orderDto, Errors bindingResult) {

        return null;
    }

    /**
     * 根据快递号查询入驻信息
     *
     * @return
     */
    @AuthToken(source = 1)
    @RequestMapping(value = "queryKauidi", method = RequestMethod.POST)
    @ResponseBody
//    @ApiOperation(value = "查询入驻")
    public com.express.common.result.Result queryKauidi(OrdersQueryDto orderDto) {
        return orderService.queryOrder(orderDto.getOrderId(), orderDto.getKuaidinum().toUpperCase());
    }
}
